home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 21 / CU Amiga Magazine's Super CD-ROM 21 (1998)(EMAP Images)(GB)[!][issue 1998-04].iso / CUCD / Games / ADoom / ADoom_src / r_segs.c < prev    next >
C/C++ Source or Header  |  1998-01-27  |  19KB  |  812 lines

  1. // Emacs style mode select   -*- C++ -*- 
  2. //-----------------------------------------------------------------------------
  3. //
  4. // $Id:$
  5. //
  6. // Copyright (C) 1993-1996 by id Software, Inc.
  7. //
  8. // This source is available for distribution and/or modification
  9. // only under the terms of the DOOM Source Code License as
  10. // published by id Software. All rights reserved.
  11. //
  12. // The source is distributed in the hope that it will be useful,
  13. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. // FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
  15. // for more details.
  16. //
  17. // $Log:$
  18. //
  19. // DESCRIPTION:
  20. //    All the clipping: columns, horizontal spans, sky columns.
  21. //
  22. //-----------------------------------------------------------------------------
  23.  
  24.  
  25. static const char
  26. rcsid[] = "$Id: r_segs.c,v 1.3 1997/01/29 20:10:19 b1 Exp $";
  27.  
  28.  
  29.  
  30.  
  31.  
  32. #include <stdlib.h>
  33.  
  34. #include "i_system.h"
  35.  
  36. #include "doomdef.h"
  37. #include "doomstat.h"
  38.  
  39. #include "r_local.h"
  40. #include "r_sky.h"
  41.  
  42.  
  43. // OPTIMIZE: closed two sided lines as single sided
  44.  
  45. // True if any of the segs textures might be visible.
  46. boolean        segtextured;    
  47.  
  48. // False if the back side is the same plane.
  49. boolean        markfloor;    
  50. boolean        markceiling;
  51.  
  52. boolean        maskedtexture;
  53. int        toptexture;
  54. int        bottomtexture;
  55. int        midtexture;
  56.  
  57.  
  58. angle_t        rw_normalangle;
  59. // angle to line origin
  60. int        rw_angle1;    
  61.  
  62. //
  63. // regular wall
  64. //
  65. int        rw_x;
  66. int        rw_stopx;
  67. angle_t        rw_centerangle;
  68. fixed_t        rw_offset;
  69. fixed_t        rw_distance;
  70. fixed_t        rw_scale;
  71. fixed_t        rw_scalestep;
  72. fixed_t        rw_midtexturemid;
  73. fixed_t        rw_toptexturemid;
  74. fixed_t        rw_bottomtexturemid;
  75.  
  76. int        worldtop;
  77. int        worldbottom;
  78. int        worldhigh;
  79. int        worldlow;
  80.  
  81. fixed_t        pixhigh;
  82. fixed_t        pixlow;
  83. fixed_t        pixhighstep;
  84. fixed_t        pixlowstep;
  85.  
  86. fixed_t        topfrac;
  87. fixed_t        topstep;
  88.  
  89. fixed_t        bottomfrac;
  90. fixed_t        bottomstep;
  91.  
  92.  
  93. lighttable_t**    walllights;
  94.  
  95. short*        maskedtexturecol;
  96.  
  97.  
  98.  
  99. //
  100. // R_RenderMaskedSegRange
  101. //
  102. void
  103. R_RenderMaskedSegRange
  104. ( drawseg_t*    ds,
  105.   int        x1,
  106.   int        x2 )
  107. {
  108.     unsigned    index;
  109.     column_t*    col;
  110.     int        lightnum;
  111.     int        texnum;
  112.     
  113.     // Calculate light table.
  114.     // Use different light tables
  115.     //   for horizontal / vertical / diagonal. Diagonal?
  116.     // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
  117.     curline = ds->curline;
  118.     frontsector = curline->frontsector;
  119.     backsector = curline->backsector;
  120.     texnum = texturetranslation[curline->sidedef->midtexture];
  121.     
  122.     lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight;
  123.  
  124.     if (curline->v1->y == curline->v2->y)
  125.     lightnum--;
  126.     else if (curline->v1->x == curline->v2->x)
  127.     lightnum++;
  128.  
  129.     if (lightnum < 0)        
  130.     walllights = scalelight[0];
  131.     else if (lightnum >= LIGHTLEVELS)
  132.     walllights = scalelight[LIGHTLEVELS-1];
  133.     else
  134.     walllights = scalelight[lightnum];
  135.  
  136.     maskedtexturecol = ds->maskedtexturecol;
  137.  
  138.     rw_scalestep = ds->scalestep;        
  139.     spryscale = ds->scale1 + (x1 - ds->x1)*rw_scalestep;
  140.     mfloorclip = ds->sprbottomclip;
  141.     mceilingclip = ds->sprtopclip;
  142.     
  143.     // find positioning
  144.     if (curline->linedef->flags & ML_DONTPEGBOTTOM)
  145.     {
  146.     dc_texturemid = frontsector->floorheight > backsector->floorheight
  147.         ? frontsector->floorheight : backsector->floorheight;
  148.     dc_texturemid = dc_texturemid + textureheight[texnum] - viewz;
  149.     }
  150.     else
  151.     {
  152.     dc_texturemid =frontsector->ceilingheight<backsector->ceilingheight
  153.         ? frontsector->ceilingheight : backsector->ceilingheight;
  154.     dc_texturemid = dc_texturemid - viewz;
  155.     }
  156.     dc_texturemid += curline->sidedef->rowoffset;
  157.             
  158.     if (fixedcolormap)
  159.     dc_colormap = fixedcolormap;
  160.     
  161.     // draw the columns
  162.     for (dc_x = x1 ; dc_x <= x2 ; dc_x++)
  163.     {
  164.     // calculate lighting
  165.     if (maskedtexturecol[dc_x] != MAXSHORT)
  166.     {
  167.         if (!fixedcolormap)
  168.         {
  169.         index = spryscale>>LIGHTSCALESHIFT;
  170.  
  171.         if (index >=  MAXLIGHTSCALE )
  172.             index = MAXLIGHTSCALE-1;
  173.  
  174.         dc_colormap = walllights[index];
  175.         }
  176.             
  177.         sprtopscreen = centeryfrac - FixedMul(dc_texturemid, spryscale);
  178.         dc_iscale = 0xffffffffu / (unsigned)spryscale;
  179.         
  180.         // draw the texture
  181.         col = (column_t *)( 
  182.         (byte *)R_GetColumn(texnum,maskedtexturecol[dc_x]) -3);
  183.             
  184. //#ifndef AMIGA
  185.         R_DrawMaskedColumn (col);
  186. //#else
  187. //        R_DrawMaskedColumnAmi (col, TYPE_NORMAL);
  188. //#endif
  189.         maskedtexturecol[dc_x] = MAXSHORT;
  190.     }
  191.     spryscale += rw_scalestep;
  192.     }
  193.     
  194. }
  195.  
  196.  
  197.  
  198.  
  199. #ifdef AMIGA
  200.  
  201. extern void R_RenderSegLoop (void);
  202.  
  203. #else
  204.  
  205. //#define DO_STATS
  206.  
  207. #ifdef DO_STATS
  208. unsigned int stats[26] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
  209. #define STATS(x) stats[x]++
  210. #else
  211. #define STATS(x)
  212. #endif
  213.  
  214.  
  215. //
  216. // R_RenderSegLoop
  217. // Draws zero, one, or two textures (and possibly a masked
  218. //  texture) for walls.
  219. // Can draw or mark the starting pixel of floor and ceiling
  220. //  textures.
  221. // CALLED: CORE LOOPING ROUTINE.
  222. //
  223. #define HEIGHTBITS        12
  224. #define HEIGHTUNIT        (1<<HEIGHTBITS)
  225.  
  226. void R_RenderSegLoop (void)
  227. {
  228.     angle_t        angle;
  229.     unsigned        index;
  230.     int            yl;
  231.     int            yh;
  232.     int            mid;
  233.     fixed_t        texturecolumn;
  234.     int            top;
  235.     int            bottom;
  236.  
  237.     //texturecolumn = 0;                // shut up compiler warning
  238.  
  239.     STATS(0);  /* 45443 */
  240.     for ( ; rw_x < rw_stopx ; rw_x++)
  241.     {
  242.         STATS(1);  /* 1603733 */
  243.     // mark floor / ceiling areas
  244.     yl = (topfrac+HEIGHTUNIT-1)>>HEIGHTBITS;
  245.  
  246.     // no space above wall?
  247.     if (yl < ceilingclip[rw_x]+1) {
  248.             STATS(2);  /* 1016131 */
  249.         yl = ceilingclip[rw_x]+1;
  250.     }
  251.  
  252.     if (markceiling)
  253.     {
  254.             STATS(3);  /* 1291140 */
  255.         top = ceilingclip[rw_x]+1;
  256.         bottom = yl-1;
  257.  
  258.         if (bottom >= floorclip[rw_x]) {
  259.                 STATS(4);  /* 50179 */
  260.         bottom = floorclip[rw_x]-1;
  261.             }
  262.         if (top <= bottom)
  263.         {
  264.                 STATS(5);  /* 439559 */
  265.         ceilingplane->top[rw_x] = top;
  266.         ceilingplane->bottom[rw_x] = bottom;
  267.         }
  268.     }
  269.         
  270.     yh = bottomfrac>>HEIGHTBITS;
  271.  
  272.     if (yh >= floorclip[rw_x]) {
  273.             STATS(6);  /* 670449 */
  274.         yh = floorclip[rw_x]-1;
  275.         }
  276.     if (markfloor)
  277.     {
  278.             STATS(7);  /* 1298743 */
  279.         top = yh+1;
  280.         bottom = floorclip[rw_x]-1;
  281.         if (top <= ceilingclip[rw_x]) {
  282.                 STATS(8);  /* 49048 */
  283.         top = ceilingclip[rw_x]+1;
  284.             }
  285.         if (top <= bottom)
  286.         {
  287.                 STATS(9);  /* 726501 */
  288.         floorplane->top[rw_x] = top;
  289.         floorplane->bottom[rw_x] = bottom;
  290.         }
  291.     }
  292.     
  293.     // texturecolumn and lighting are independent of wall tiers
  294.     if (segtextured)
  295.     {
  296.             STATS(10);  /* 1261482 */
  297.         // calculate texture offset
  298.         angle = (rw_centerangle + xtoviewangle[rw_x])>>ANGLETOFINESHIFT;
  299.         texturecolumn = rw_offset-FixedMul(finetangent[angle],rw_distance);
  300.         texturecolumn >>= FRACBITS;
  301.         // calculate lighting
  302.         index = rw_scale>>LIGHTSCALESHIFT;
  303.  
  304.         if (index >=  MAXLIGHTSCALE ) {
  305.                 STATS(11);  /* 169980 */
  306.         index = MAXLIGHTSCALE-1;
  307.             }
  308.         dc_colormap = walllights[index];
  309.         dc_x = rw_x;
  310.         dc_iscale = 0xffffffffu / (unsigned)rw_scale;
  311.     }
  312.     
  313.     // draw the wall tiers
  314.     if (midtexture)
  315.     {
  316.             STATS(12);  /* 560607 */
  317.         // single sided line
  318.         dc_yl = yl;
  319.         dc_yh = yh;
  320.         dc_texturemid = rw_midtexturemid;
  321.         dc_source = R_GetColumn(midtexture,texturecolumn);
  322.         colfunc ();
  323.         ceilingclip[rw_x] = viewheight;
  324.         floorclip[rw_x] = -1;
  325.     }
  326.     else
  327.     {
  328.             STATS(13);  /* 1043126 */
  329.         // two sided line
  330.         if (toptexture)
  331.         {
  332.                 STATS(14);  /* 314333 */
  333.         // top wall
  334.         mid = pixhigh>>HEIGHTBITS;
  335.         pixhigh += pixhighstep;
  336.  
  337.         if (mid >= floorclip[rw_x]) {
  338.                     STATS(15);  /* 45511 */
  339.             mid = floorclip[rw_x]-1;
  340.                 }
  341.         if (mid >= yl)
  342.         {
  343.                     STATS(16);  /* 139708 */
  344.             dc_yl = yl;
  345.             dc_yh = mid;
  346.             dc_texturemid = rw_toptexturemid;
  347.             dc_source = R_GetColumn(toptexture,texturecolumn);
  348.             colfunc ();
  349.             ceilingclip[rw_x] = mid;
  350.         }
  351.         else {
  352.                     STATS(17);  /* 174625 */
  353.             ceilingclip[rw_x] = yl-1;
  354.                 }
  355.         }
  356.         else
  357.         {
  358.                 STATS(18);  /* 728793 */
  359.         // no top wall
  360.         if (markceiling) {
  361.                     STATS(19);  /* 439926 */
  362.             ceilingclip[rw_x] = yl-1;
  363.                 }
  364.         }
  365.             
  366.         if (bottomtexture)
  367.         {
  368.                 STATS(20);  /* 446785 */
  369.         // bottom wall
  370.         mid = (pixlow+HEIGHTUNIT-1)>>HEIGHTBITS;
  371.         pixlow += pixlowstep;
  372.  
  373.         // no space above wall?
  374.         if (mid <= ceilingclip[rw_x]) {
  375.                     STATS(21);  /* 67461 */
  376.             mid = ceilingclip[rw_x]+1;
  377.         }
  378.         if (mid <= yh)
  379.         {
  380.                     STATS(22);  /* 366880 */
  381.             dc_yl = mid;
  382.             dc_yh = yh;
  383.             dc_texturemid = rw_bottomtexturemid;
  384.             dc_source = R_GetColumn(bottomtexture,
  385.                         texturecolumn);
  386.             colfunc ();
  387.             floorclip[rw_x] = mid;
  388.         }
  389.         else {
  390.                     STATS(23);  /* 79905 */
  391.             floorclip[rw_x] = yh+1;
  392.                 }
  393.         }
  394.         else
  395.         {
  396.                 STATS(24);  /* 596341 */
  397.         // no bottom wall
  398.         if (markfloor)
  399.             floorclip[rw_x] = yh+1;
  400.         }
  401.             
  402.         if (maskedtexture)
  403.         {
  404.                 STATS(25);  /* 0 */
  405.         // save texturecol
  406.         //  for backdrawing of masked mid texture
  407.         maskedtexturecol[rw_x] = texturecolumn;
  408.         }
  409.     }
  410.         
  411.     rw_scale += rw_scalestep;
  412.     topfrac += topstep;
  413.     bottomfrac += bottomstep;
  414.  
  415.     }
  416. }
  417.  
  418. #ifdef DO_STATS
  419. void _STDdo_stats (void)
  420. {
  421.   int i;
  422.  
  423.   for (i = 0; i < 26; i++)
  424.      printf ("stats[%2d] = %u\n", i, stats[i]);
  425. }
  426. #endif
  427.  
  428. #endif
  429.  
  430.  
  431.  
  432.  
  433. //
  434. // R_StoreWallRange
  435. // A wall segment will be drawn
  436. //  between start and stop pixels (inclusive).
  437. //
  438. void
  439. R_StoreWallRange
  440. ( int    start,
  441.   int    stop )
  442. {
  443.     fixed_t        hyp;
  444.     fixed_t        sineval;
  445.     angle_t        distangle, offsetangle;
  446.     fixed_t        vtop;
  447.     int            lightnum;
  448.  
  449.     // don't overflow and crash
  450.     if (ds_p == &drawsegs[MAXDRAWSEGS])
  451.     return;        
  452.         
  453. #ifdef RANGECHECK
  454.     if (start >=viewwidth || start > stop)
  455.     I_Error ("Bad R_RenderWallRange: %i to %i", start , stop);
  456. #endif
  457.     
  458.     sidedef = curline->sidedef;
  459.     linedef = curline->linedef;
  460.  
  461.     // mark the segment as visible for auto map
  462.     linedef->flags |= ML_MAPPED;
  463.     
  464.     // calculate rw_distance for scale calculation
  465.     rw_normalangle = curline->angle + ANG90;
  466.     offsetangle = iabs(rw_normalangle-rw_angle1);
  467.     
  468.     if (offsetangle > ANG90)
  469.     offsetangle = ANG90;
  470.  
  471.     distangle = ANG90 - offsetangle;
  472.     hyp = R_PointToDist (curline->v1->x, curline->v1->y);
  473.     sineval = finesine[distangle>>ANGLETOFINESHIFT];
  474.     rw_distance = FixedMul (hyp, sineval);
  475.         
  476.     
  477.     ds_p->x1 = rw_x = start;
  478.     ds_p->x2 = stop;
  479.     ds_p->curline = curline;
  480.     rw_stopx = stop+1;
  481.     
  482.     // calculate scale at both ends and step
  483.     ds_p->scale1 = rw_scale = 
  484.     R_ScaleFromGlobalAngle (viewangle + xtoviewangle[start]);
  485.     
  486.     if (stop > start )
  487.     {
  488.     ds_p->scale2 = R_ScaleFromGlobalAngle (viewangle + xtoviewangle[stop]);
  489.     ds_p->scalestep = rw_scalestep = 
  490.         (ds_p->scale2 - rw_scale) / (stop-start);
  491.     }
  492.     else
  493.     {
  494.     // UNUSED: try to fix the stretched line bug
  495. #if 0
  496.     if (rw_distance < FRACUNIT/2)
  497.     {
  498.         fixed_t        trx,try;
  499.         fixed_t        gxt,gyt;
  500.  
  501.         trx = curline->v1->x - viewx;
  502.         try = curline->v1->y - viewy;
  503.             
  504.         gxt = FixedMul(trx,viewcos); 
  505.         gyt = -FixedMul(try,viewsin); 
  506.         ds_p->scale1 = FixedDiv(projection, gxt-gyt)<<detailshift;
  507.     }
  508. #endif
  509.     ds_p->scale2 = ds_p->scale1;
  510.     }
  511.     
  512.     // calculate texture boundaries
  513.     //  and decide if floor / ceiling marks are needed
  514.     worldtop = frontsector->ceilingheight - viewz;
  515.     worldbottom = frontsector->floorheight - viewz;
  516.     
  517.     midtexture = toptexture = bottomtexture = maskedtexture = 0;
  518.     ds_p->maskedtexturecol = NULL;
  519.     
  520.     if (!backsector)
  521.     {
  522.     // single sided line
  523.     midtexture = texturetranslation[sidedef->midtexture];
  524.     // a single sided line is terminal, so it must mark ends
  525.     markfloor = markceiling = true;
  526.     if (linedef->flags & ML_DONTPEGBOTTOM)
  527.     {
  528.         vtop = frontsector->floorheight +
  529.         textureheight[sidedef->midtexture];
  530.         // bottom of texture at bottom
  531.         rw_midtexturemid = vtop - viewz;    
  532.     }
  533.     else
  534.     {
  535.         // top of texture at top
  536.         rw_midtexturemid = worldtop;
  537.     }
  538.     rw_midtexturemid += sidedef->rowoffset;
  539.  
  540.     ds_p->silhouette = SIL_BOTH;
  541.     ds_p->sprtopclip = screenheightarray;
  542.     ds_p->sprbottomclip = negonearray;
  543.     ds_p->bsilheight = MAXINT;
  544.     ds_p->tsilheight = MININT;
  545.     }
  546.     else
  547.     {
  548.     // two sided line
  549.     ds_p->sprtopclip = ds_p->sprbottomclip = NULL;
  550.     ds_p->silhouette = 0;
  551.     
  552.     if (frontsector->floorheight > backsector->floorheight)
  553.     {
  554.         ds_p->silhouette = SIL_BOTTOM;
  555.         ds_p->bsilheight = frontsector->floorheight;
  556.     }
  557.     else if (backsector->floorheight > viewz)
  558.     {
  559.         ds_p->silhouette = SIL_BOTTOM;
  560.         ds_p->bsilheight = MAXINT;
  561.         // ds_p->sprbottomclip = negonearray;
  562.     }
  563.     
  564.     if (frontsector->ceilingheight < backsector->ceilingheight)
  565.     {
  566.         ds_p->silhouette |= SIL_TOP;
  567.         ds_p->tsilheight = frontsector->ceilingheight;
  568.     }
  569.     else if (backsector->ceilingheight < viewz)
  570.     {
  571.         ds_p->silhouette |= SIL_TOP;
  572.         ds_p->tsilheight = MININT;
  573.         // ds_p->sprtopclip = screenheightarray;
  574.     }
  575.         
  576.     if (backsector->ceilingheight <= frontsector->floorheight)
  577.     {
  578.         ds_p->sprbottomclip = negonearray;
  579.         ds_p->bsilheight = MAXINT;
  580.         ds_p->silhouette |= SIL_BOTTOM;
  581.     }
  582.     
  583.     if (backsector->floorheight >= frontsector->ceilingheight)
  584.     {
  585.         ds_p->sprtopclip = screenheightarray;
  586.         ds_p->tsilheight = MININT;
  587.         ds_p->silhouette |= SIL_TOP;
  588.     }
  589.     
  590.     worldhigh = backsector->ceilingheight - viewz;
  591.     worldlow = backsector->floorheight - viewz;
  592.         
  593.     // hack to allow height changes in outdoor areas
  594.     if (frontsector->ceilingpic == skyflatnum 
  595.         && backsector->ceilingpic == skyflatnum)
  596.     {
  597.         worldtop = worldhigh;
  598.     }
  599.     
  600.             
  601.     if (worldlow != worldbottom 
  602.         || backsector->floorpic != frontsector->floorpic
  603.         || backsector->lightlevel != frontsector->lightlevel)
  604.     {
  605.         markfloor = true;
  606.     }
  607.     else
  608.     {
  609.         // same plane on both sides
  610.         markfloor = false;
  611.     }
  612.     
  613.             
  614.     if (worldhigh != worldtop 
  615.         || backsector->ceilingpic != frontsector->ceilingpic
  616.         || backsector->lightlevel != frontsector->lightlevel)
  617.     {
  618.         markceiling = true;
  619.     }
  620.     else
  621.     {
  622.         // same plane on both sides
  623.         markceiling = false;
  624.     }
  625.     
  626.     if (backsector->ceilingheight <= frontsector->floorheight
  627.         || backsector->floorheight >= frontsector->ceilingheight)
  628.     {
  629.         // closed door
  630.         markceiling = markfloor = true;
  631.     }
  632.     
  633.  
  634.     if (worldhigh < worldtop)
  635.     {
  636.         // top texture
  637.         toptexture = texturetranslation[sidedef->toptexture];
  638.         if (linedef->flags & ML_DONTPEGTOP)
  639.         {
  640.         // top of texture at top
  641.         rw_toptexturemid = worldtop;
  642.         }
  643.         else
  644.         {
  645.         vtop =
  646.             backsector->ceilingheight
  647.             + textureheight[sidedef->toptexture];
  648.         
  649.         // bottom of texture
  650.         rw_toptexturemid = vtop - viewz;    
  651.         }
  652.     }
  653.     if (worldlow > worldbottom)
  654.     {
  655.         // bottom texture
  656.         bottomtexture = texturetranslation[sidedef->bottomtexture];
  657.  
  658.         if (linedef->flags & ML_DONTPEGBOTTOM )
  659.         {
  660.         // bottom of texture at bottom
  661.         // top of texture at top
  662.         rw_bottomtexturemid = worldtop;
  663.         }
  664.         else    // top of texture at top
  665.         rw_bottomtexturemid = worldlow;
  666.     }
  667.     rw_toptexturemid += sidedef->rowoffset;
  668.     rw_bottomtexturemid += sidedef->rowoffset;
  669.     
  670.     // allocate space for masked texture tables
  671.     if (sidedef->midtexture)
  672.     {
  673.         // masked midtexture
  674.         maskedtexture = true;
  675.         ds_p->maskedtexturecol = maskedtexturecol = lastopening - rw_x;
  676.         lastopening += rw_stopx - rw_x;
  677.     }
  678.     }
  679.     
  680.     // calculate rw_offset (only needed for textured lines)
  681.     segtextured = midtexture | toptexture | bottomtexture | maskedtexture;
  682.  
  683.     if (segtextured)
  684.     {
  685.     offsetangle = rw_normalangle-rw_angle1;
  686.     
  687.     if (offsetangle > ANG180)
  688.         offsetangle = -offsetangle;
  689.  
  690.     if (offsetangle > ANG90)
  691.         offsetangle = ANG90;
  692.  
  693.     sineval = finesine[offsetangle >>ANGLETOFINESHIFT];
  694.     rw_offset = FixedMul (hyp, sineval);
  695.  
  696.     if (rw_normalangle-rw_angle1 < ANG180)
  697.         rw_offset = -rw_offset;
  698.  
  699.     rw_offset += sidedef->textureoffset + curline->offset;
  700.     rw_centerangle = ANG90 + viewangle - rw_normalangle;
  701.     
  702.     // calculate light table
  703.     //  use different light tables
  704.     //  for horizontal / vertical / diagonal
  705.     // OPTIMIZE: get rid of LIGHTSEGSHIFT globally
  706.     if (!fixedcolormap)
  707.     {
  708.         lightnum = (frontsector->lightlevel >> LIGHTSEGSHIFT)+extralight;
  709.  
  710.         if (curline->v1->y == curline->v2->y)
  711.         lightnum--;
  712.         else if (curline->v1->x == curline->v2->x)
  713.         lightnum++;
  714.  
  715.         if (lightnum < 0)        
  716.         walllights = scalelight[0];
  717.         else if (lightnum >= LIGHTLEVELS)
  718.         walllights = scalelight[LIGHTLEVELS-1];
  719.         else
  720.         walllights = scalelight[lightnum];
  721.     }
  722.     }
  723.     
  724.     // if a floor / ceiling plane is on the wrong side
  725.     //  of the view plane, it is definitely invisible
  726.     //  and doesn't need to be marked.
  727.     
  728.   
  729.     if (frontsector->floorheight >= viewz)
  730.     {
  731.     // above view plane
  732.     markfloor = false;
  733.     }
  734.     
  735.     if (frontsector->ceilingheight <= viewz 
  736.     && frontsector->ceilingpic != skyflatnum)
  737.     {
  738.     // below view plane
  739.     markceiling = false;
  740.     }
  741.  
  742.     
  743.     // calculate incremental stepping values for texture edges
  744.     worldtop >>= 4;
  745.     worldbottom >>= 4;
  746.     
  747.     topstep = -FixedMul (rw_scalestep, worldtop);
  748.     topfrac = (centeryfrac>>4) - FixedMul (worldtop, rw_scale);
  749.  
  750.     bottomstep = -FixedMul (rw_scalestep,worldbottom);
  751.     bottomfrac = (centeryfrac>>4) - FixedMul (worldbottom, rw_scale);
  752.     
  753.  
  754.     if (backsector)
  755.     {    
  756.     worldhigh >>= 4;
  757.     worldlow >>= 4;
  758.  
  759.     if (worldhigh < worldtop)
  760.     {
  761.         pixhigh = (centeryfrac>>4) - FixedMul (worldhigh, rw_scale);
  762.         pixhighstep = -FixedMul (rw_scalestep,worldhigh);
  763.     }
  764.     
  765.     if (worldlow > worldbottom)
  766.     {
  767.         pixlow = (centeryfrac>>4) - FixedMul (worldlow, rw_scale);
  768.         pixlowstep = -FixedMul (rw_scalestep,worldlow);
  769.     }
  770.     }
  771.     
  772.     // render it
  773.     if (markceiling)
  774.     ceilingplane = R_CheckPlane (ceilingplane, rw_x, rw_stopx-1);
  775.     
  776.     if (markfloor)
  777.     floorplane = R_CheckPlane (floorplane, rw_x, rw_stopx-1);
  778.  
  779.     R_RenderSegLoop ();
  780.  
  781.     
  782.     // save sprite clipping info
  783.     if ( ((ds_p->silhouette & SIL_TOP) || maskedtexture)
  784.      && !ds_p->sprtopclip)
  785.     {
  786.     memcpy (lastopening, ceilingclip+start, 2*(rw_stopx-start));
  787.     ds_p->sprtopclip = lastopening - start;
  788.     lastopening += rw_stopx - start;
  789.     }
  790.     
  791.     if ( ((ds_p->silhouette & SIL_BOTTOM) || maskedtexture)
  792.      && !ds_p->sprbottomclip)
  793.     {
  794.     memcpy (lastopening, floorclip+start, 2*(rw_stopx-start));
  795.     ds_p->sprbottomclip = lastopening - start;
  796.     lastopening += rw_stopx - start;    
  797.     }
  798.  
  799.     if (maskedtexture && !(ds_p->silhouette&SIL_TOP))
  800.     {
  801.     ds_p->silhouette |= SIL_TOP;
  802.     ds_p->tsilheight = MININT;
  803.     }
  804.     if (maskedtexture && !(ds_p->silhouette&SIL_BOTTOM))
  805.     {
  806.     ds_p->silhouette |= SIL_BOTTOM;
  807.     ds_p->bsilheight = MAXINT;
  808.     }
  809.     ds_p++;
  810. }
  811.  
  812.